# 这个程序的功能是从一个配置文件中解析出菜单项，并将其构建为树状结构，最后以树状格式打印出来。
from typing import Optional, List
from pydantic import BaseModel
import sys
from pathlib import Path
import os

debug=True

def get_self_path() -> Path:
    """获取本软件的全路径文件名"""
    return Path(sys.argv[0]).resolve()

class 菜单项(BaseModel):
    菜单文字: str
    级别: int = 0
    # 命令行: Optional[str] = None
    前导符:Optional[str] = None
    下级菜单: Optional[List['菜单项']] = None


def 解析行(line: str) -> Optional[tuple]:
    temp = line.strip()  # 前后空白都剔除
    if len(temp) == 0 or temp.startswith("#") or temp.startswith(";"):
        return None  # 注释行和空行剔除不用处理
    text = line.rstrip()  # 1. 剔除尾部空白
    前导str = text[:len(text) - len(text.strip())]
    级别 = 前导str.count('\t')
    if 级别 != len(前导str):
        return [-1, "行Keiser部分不允许有空格，只允许有tab"]
    parts = text.strip().split(" ", 1)
    return [级别, parts[0], parts[1].strip() if len(parts) > 1 else None]


def 解析菜单配置文件(file_path: str) -> List[菜单项]:
    我的菜单 = []
    if debug:
        print("当前工作目录:", os.getcwd())
        print(f"打开配置文件： {file_path}，剔除空行和注释行之后，有效内容：")
    recs = []
    with open(file_path, 'r', encoding='utf-8') as file:
        lines = file.readlines()
    for i, t in enumerate(lines, 1):
        r = 解析行(t)
        if r is None:
            continue
        # rec=菜单项(级别=r[0],菜单文字=r[1]+((" "+r[2]) if r[2]!=None else ""))
        recs.append(r)
    if debug:
        for i, t in enumerate(recs, 1):
            print(i, t)
        print("======================")

    def getitem(p: int, recs) -> (int, 菜单项):
        if p > len(recs):
            return (p, None)
        temp = 菜单项(级别=recs[p][0],菜单文字 = recs[p][1] + ((" " + recs[p][2]) if recs[p][2] != None else ""))
        # 检查是否有下级菜单
        subitem = []
        np = p + 1  # 从当前行的下一行开始检查
        while np < len(recs) and recs[np][0] > recs[p][0]:  # 如果下一行存在，且其级别小于本行，是本行的子菜单
            pok, onesubitem = getitem(np, recs)  #从这一行取一个完整菜单项，返回 未处理的行号 和 已经处理的菜单对象
            subitem.append(onesubitem) #取得的这菜单向，加入本菜单子菜单列表
            np = pok #直至指向下一个未处理的行
        if len(subitem) > 0:
            temp.下级菜单 = subitem
        else:
            temp.前导符=recs[p][1]
            if temp.前导符 == "<清除>":
                temp.前导符 = ""
        return (np, temp)

    p = 0
    while p < len(recs):
        p, xxx = getitem(p, recs)
        if xxx:
            我的菜单.append(xxx)
    return 我的菜单


def showitems(item: 菜单项, tab=0):
    if item.下级菜单:
        print(f"{tab * '↔ '}【{item.菜单文字}】 '{item.前导符}'")
        for r in item.下级菜单:
            showitems(r, tab + 1)
    else:
        print(f"{tab * '↔ '}[{item.菜单文字}] '{item.前导符}'")


# 使用示例
if __name__ == "__main__":
    debug=True
    菜单定义 = 解析菜单配置文件('fnmark_配置.ini')
    for i, xxx in enumerate(菜单定义, 1):
        print(f"===================解析出菜单 {i}============================")
        showitems(xxx)
